/*
 * Copyright (c) 2024 endless-sky
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// 系统头文件
#include <stdio.h>
#include <thread>
#include <chrono>
#include <mutex>
#include <condition_variable>
#include <memory>

// 第三方库头文件
#include "nlohmann/json.hpp"

// 基础库头文件
#include "utils_time_cost.h"
#include "utils_log.h"
#include "utils_init.h"

// 公共组件头文件
#include "common_init.h"
#include "common_version.h"
#include "common_product_definition.h"
#include "common_module_registry.h"

// 各模块头文件
#include "media_service.h"
#include "storage_init.h"
#include "event_init.h"
#include "record_init.h"
#include "stream_service.h"
#include "web_server_init.h"
#include "cloud_model.h"
#include "upgrade.h"
#include "restful.h"
#include "system_service.h"
#include "file_manager.h"
#include "discovery_server.h"
#include "network.h"
#include "ai_talk.h"
#include "peripheral.h"
#include "algo_manager.h"
#include "onvif_interface.h"
#include "gb28181_interface.h"

// 常量定义
namespace {
const int LOG_MAX_FILE_SIZE_KB = 256;
const int LOG_MAX_FILES = 4;
const int MEM_TOTAL_SIZE_MB = 3;
const int MEM_CHUNK_SIZE = 1024;
const int MEM_ALIGN_SIZE = 4;
const int EVENT_DB_MAX_OPEN_FILES = 100;
const int EVENT_MAX_EVENTS = 1000;
} // namespace

#ifdef __cplusplus
extern "C" {
#endif

int32_t sky_start();

#ifdef __cplusplus
}
#endif

using namespace El;

int main(int argc, char **argv)
{
    (void)argc;
    (void)argv;

    try {
        // 初始化基础库
        Utils::TimeCost timeCost("main", true);
        nlohmann::json config;
        config["log"]["enableToFile"] = true;
        config["log"]["filePath"] = "/mnt/log/app.log";
        config["log"]["maxFileSize"] = LOG_MAX_FILE_SIZE_KB * 1024;
        config["log"]["maxFiles"] = LOG_MAX_FILES;
        config["log"]["level"] = "info";
        config["mem"]["totalSize"] = MEM_TOTAL_SIZE_MB * 1024 * 1024;
        config["mem"]["chunkSize"] = MEM_CHUNK_SIZE;
        config["mem"]["alignSize"] = MEM_ALIGN_SIZE;
        Utils::base_init(config);
        timeCost.Mark("base_init");

        // 初始化公共组件
        config.clear();
        config["general"] = "/mnt/config/config";
        config["default"] = "/usr/etc/custom/default";
        config["product"] = "/usr/etc/custom/product.yaml";
        Common::common_init(config);
        timeCost.Mark("common_init");

        // 打印产品信息
        std::string deviceModel;
        std::string serialNumber;
        Common::ProductDefinition::GetInstance().GetValue("device_model", deviceModel);
        Common::ProductDefinition::GetInstance().GetValue("serial_number", serialNumber);
        EL_INFO("main start product:{} serial:{} version:{}", deviceModel.c_str(), serialNumber.c_str(),
                Common::VersionManager::GetInstance().GetVersionFull().c_str());

        // 初始化事件
        config.clear();
        config["db_path"] = "/mnt/data/event.db";
        config["db_size"] = 1 * 1024 * 1024;
        config["db_max_open_files"] = EVENT_DB_MAX_OPEN_FILES;
        config["max_events"] = EVENT_MAX_EVENTS;
        Event::event_init(config);
        timeCost.Mark("event_init");

        // 初始化系统服务
        config.clear();
        if (!SystemService::SystemService::GetInstance().Start()) {
            EL_WARN("System service may not be fully initialized");
        }
        timeCost.Mark("system_server_init");

        // 初始化外设
        if (!Peripheral::PeripheralService::GetInstance().Start()) {
            EL_ERROR("Peripheral service failed to start.");
        }
        timeCost.Mark("peripheral_init");

        // 初始化文件管理
        config.clear();
        if (!FileManager::IFileManager::GetInstance().Start()) {
            EL_ERROR("File manager failed to start.");
        }
        timeCost.Mark("file_manager_init");

        // 初始化网络服务（必须在其他服务之前初始化，为ifup -a提供配置文件）
        if (!Network::Network::GetInstance().Start()) {
            EL_ERROR("Network module failed to initialize.");
        }
        timeCost.Mark("network_init");

        // 初始化音视频流
        if (!Media::MediaService::GetInstance().Start()) {
            EL_ERROR("Media service failed to start.");
        }
        timeCost.Mark("media_service start");

        // 初始化存储
        config.clear();
        Storage::storage_init(config);
        timeCost.Mark("storage_init");

        // 初始化录像
        config.clear();
        Record::record_init(config);
        timeCost.Mark("record_init");

        // 初始化算法管理器
        config.clear();
        Algo::IAlgoManager::GetInstance().Start();
        timeCost.Mark("algo_manager_init");

        // 启动流媒体服务
        config.clear();
        if (!StreamService::StreamService::GetInstance().Start()) {
            EL_ERROR("Stream service failed to start.");
        }
        timeCost.Mark("stream_service start");

        // 设备搜索服务
        if (!Discovery::IDiscoveryServer::GetInstance().Start()) {
            EL_ERROR("Discovery server failed to start.");
        }
        timeCost.Mark("discovery_server_start");

        // 启动web服务
        config.clear();
        config["web_dir"] = "/mnt/assets/web";
        WebServer::web_server_init(config);
        timeCost.Mark("web_server_init");

        // 启动restful服务
        config.clear();
        if (!Restful::IRestfulService::GetInstance().Start()) {
            EL_ERROR("Restful service failed to start.");
        }
        timeCost.Mark("restful_init");

        // 启动升级服务
        if (!Upgrade::IUpgradeService::GetInstance().Start()) {
            EL_WARN("Failed to start upgrade service, but continuing");
        }
        timeCost.Mark("upgrade_service_start");

        // 启动阿里云服务
        if (!El::Cloud::AliyunService::GetInstance().Start()) {
            EL_WARN("Aliyun service failed to start, but continuing");
        }
        timeCost.Mark("aliyun_service_start");

        // 启动国标服务
        std::unique_ptr<GB28181::IGB28181Service> gb28181Service;
        auto gbFactory = GB28181::CreateGB28181Factory();
        if (gbFactory) {
            gb28181Service = gbFactory->CreateService();
            if (!gb28181Service || !gb28181Service->Start()) {
                EL_ERROR("GB28181 service start failed");
            }
        } else {
            EL_ERROR("GB28181 factory creation failed");
        }
        timeCost.Mark("gb28181_start");

        // 启动ONVIF服务
        std::unique_ptr<Onvif::IOnvifServer> onvifServer;
        auto onvifFactory = Onvif::CreateOnvifServerFactory();
        if (onvifFactory) {
            onvifServer = onvifFactory->CreateServer();
            if (!onvifServer || !onvifServer->Start()) {
                EL_ERROR("ONVIF service start failed");
            }
        } else {
            EL_ERROR("ONVIF factory creation failed");
        }
        timeCost.Mark("onvif_start");

        // 用条件变量阻塞
        std::mutex mutex;
        std::unique_lock<std::mutex> lock(mutex);
        std::condition_variable cond;
        cond.wait(lock);
    } catch (const std::exception &e) {
        EL_ERROR("Exception in main: {}", e.what());
        return -1;
    } catch (...) {
        EL_ERROR("Unknown exception in main");
        return -1;
    }

    return 0;
}
